import json

import numpy as np
from pydub import AudioSegment


def analyze_silence(audio_file, silence_thresh=-50, min_silence_len=10000, output_json=None):
    """
    分析音频文件中的静音段，并输出静音的起始和结束时间。

    :param audio_file: 音频文件路径
    :param silence_thresh: 静音阈值（dBFS），默认值为 -50
    :param min_silence_len: 最小静音长度（毫秒），默认值为 1000
    """
    # 加载音频文件
    audio = AudioSegment.from_file(audio_file)

    # 打印音频总时长
    total_duration = len(audio)  # 总时长以毫秒为单位
    print(f"音频总时长: {total_duration / 1000:.2f}秒")

    # 将音频数据转换为 numpy 数组
    samples = np.array(audio.get_array_of_samples())

    # 计算音频的分贝值
    # dBFS = 20 * log10(sample_value / max_value)
    max_value = np.max(np.abs(samples))  # 获取样本的最大值
    db_values = 20 * np.log10(np.abs(samples) / max_value)  # 计算每个样本的 dBFS 值

    # 检测静音段
    silent_ranges = []
    is_silence = False
    start = None

    for i in range(len(db_values)):
        if db_values[i] < silence_thresh:  # 当前样本小于静音阈值
            if not is_silence:  # 如果之前不是静音
                is_silence = True
                start = i  # 记录静音段的起始位置
        else:
            if is_silence:  # 如果之前是静音
                is_silence = False
                end = i  # 记录静音段的结束位置
                # 计算静音段的长度
                silence_duration = (end - start) / audio.frame_rate * 1000  # 转换为毫秒
                if silence_duration >= min_silence_len:  # 检查静音长度
                    new_silence = {
                        "start_time": start / audio.frame_rate,
                        "end_time": end / audio.frame_rate,
                        "duration": silence_duration / 1000  # 转换为秒
                    }
                    # 检查是否已经存在相同或重叠的静音段
                    if not any(
                        (existing["start_time"] < new_silence["end_time"] and
                         existing["end_time"] > new_silence["start_time"])
                        for existing in silent_ranges
                    ):
                        silent_ranges.append(new_silence)  # 添加有效的静音段

    # 输出静音段的起始和结束时间
    for silence in silent_ranges:
        print(f"静音段: 起始时间: {silence['start_time']:.2f}秒, 结束时间: {silence['end_time']:.2f}秒, 持续时间: {silence['duration']:.2f}秒")

    # 如果指定了输出 JSON 文件路径，则写入静音段信息
    if output_json:
        with open(output_json, 'w') as json_file:
            json.dump(silent_ranges, json_file, indent=4)
        print(f"静音段信息已保存到 {output_json}")


if __name__ == "__main__":
    audio_file = "/Users/maweidong/source/video_audio_inspector/libs/纯音频.m4a"
    analyze_silence(audio_file, -50, 10000)
